﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel.DataAnnotations;
using System.ComponentModel;
using System.Xml.Serialization;

namespace ViewMaker.Core.Controls
{
    /// <summary>
    /// コンボボックスViewコントロール
    /// </summary>
    public class ComboBoxViewControl : ListViewControl
    {
        /// <summary>
        /// プロパティ定数
        /// </summary>
        public new class Properties : ListViewControl.Properties
        {
            public const string IsEditable = "IsEditable";
            public const string EnableSetNullByDel = "EnableSetNullByDelKey";
        }

#if !SILVERLIGHT
        /// <summary>
        /// コンボボックスが編集可能か
        /// </summary>
        public bool IsEditable { get; set; }
#else
        /// <summary>
        /// ItemsSourceで選択されたデータの値を示すプロパティのパス
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "SelectedValueList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        [ViewProperty(ComboBoxViewControl.Properties.IsEnabled, "IsEnableDisplayAndSelectedPath")]
        public override string SelectedValuePath
        {
            get { return base.SelectedValuePath; }
            set { base.SelectedValuePath = value; OnPropertyChanged("SelectedValuePath"); OnPropertyChanged("IsEnableIsEditable"); }
        }

        /// <summary>
        /// ItemsSourceの各アイテムの表示に利用するプロパティのパス
        /// </summary>
        [View(ViewControlType.ComboBox)]
        [ViewProperty(ComboBoxViewControl.Properties.ItemsSource, "SelectedValueList")]
        [ViewProperty(ComboBoxViewControl.Properties.IsEditable, true)]
        [ViewProperty(ComboBoxViewControl.Properties.IsEnabled, "IsEnableDisplayAndSelectedPath")]
        public override string DisplayMemberPath
        {
            get { return base.DisplayMemberPath; }
            set { base.DisplayMemberPath = value; OnPropertyChanged("DisplayMemberPath"); OnPropertyChanged("IsEnableIsEditable"); }
        }

        /// <summary>
        /// 編集可能か？
        /// </summary>
        [ViewProperty(ViewControl.Properties.IsEnabled, "IsEnableIsEditable")]
        public bool IsEditable
        {
            get { return _isEditable; }
            set { _isEditable = value; OnPropertyChanged("IsEnabled"); OnPropertyChanged("IsEnableDisplayAndSelectedPath"); }
        }
        private bool _isEditable;

        [Display(Name = "")]
        [XmlIgnore]
        [View(ViewControlType.Hyperlink)]
        [ViewProperty(HyperlinkViewControl.Properties.Command, "EditItemsCommand")]
        [ViewProperty(HyperlinkViewControl.Properties.IsEnabled, "IsEnableDisplayAndSelectedPath")]
        public override string EditItemsLink { get { return base.EditItemsLink; } }

        /// <summary>
        /// ItemsList編集コマンドのリンク
        /// </summary>
        [Browsable(false)]
        public bool IsEnableDisplayAndSelectedPath { get { return !IsEditable; } }

        /// <summary>
        /// ItemsList編集コマンドのリンクの有効/無効
        /// </summary>
        [Browsable(false)]
        public bool IsEnableIsEditable { get { return string.IsNullOrEmpty(SelectedValuePath) && string.IsNullOrEmpty(DisplayMemberPath); } }

#endif

        [Display(Description = "enable to set null value by delete key")]
        public bool EnableSetNullByDel { get; set; }

        /// <summary>
        /// コンストラクタ
        /// </summary>
        public ComboBoxViewControl()
        {
            ControlType = ViewControlType.ComboBox;
        }

        /// <summary>
        /// Xamlを生成する
        /// </summary>
        /// <param name="parent"></param>
        /// <returns></returns>
        public override List<XamlNode> CreateXaml(XamlNode parent)
        {
            var list = base.CreateXaml(parent);
#if !SILVERLIGHT
            var node = parent.CreateElement("ComboBox");
            if (IsEditable)
            {
                SetBindingAttribute(node, "Text", Item.BindPath, false);
                node.SetAttribute("IsEditable", IsEditable.ToString());
            }
            else
            {
                BindSelectedItem(node);
            }
            SetBindingAttribute(node, "ItemsSource", ItemsSource, true);
            if (ItemsList.Count > 0)
            {
                var items = node.AddElement("ComboBox.Items");
                foreach (var listItem in Items)
                {
                    var ele = items.CreateElement("system", "clr-namespace:System;assembly=mscorlib", "String");
                    items.AppendChild(ele).InnerText = listItem;
                }
            }
            var style = CreateStyle(node, "ComboBoxItem");
            if (style != null) node.AddElement("ComboBox.Resources").AppendChild(style);
            if (!string.IsNullOrEmpty(SelectionChangedCommand)) AddBehavior(node, "SelectionChangedBehavior", SelectionChangedCommand);
            if (EnableSetNullByDel) node.SetAttribute("vg:ComboBoxDelKeyBehavior.IsEnabled", "clr-namespace:ViewMaker.Core.Wpf;assembly=ViewMaker.Core", "true");
#else
            XamlNode node;
            if (IsEditable)
            {
                node = parent.CreateElement("input", "clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Input", "AutoCompleteBox");
                SetBindingAttribute(node, "ItemsSource", ItemsSource, true);
                SetBindingAttribute(node, "Text", Item.BindPath, Item.IsOneWay);
                node.SetAttribute("MinimumPrefixLength", "0");
                node.SetAttribute("FilterMode", "None");
                if (!string.IsNullOrEmpty(SelectionChangedCommand)) AddBehavior(node, "AutoCompleteBoxSelectionChangedBehavior", SelectionChangedCommand);
            }
            else
            {
                node = parent.CreateElement("ComboBox");
                SetBindingAttribute(node, "ItemsSource", ItemsSource, true);
                if (ItemsList.Count > 0)
                {
                    var items = node.AddElement("ComboBox.Items");
                    foreach (var listItem in Items)
                    {
                        var ele = items.CreateElement("system", "clr-namespace:System;assembly=mscorlib", "String");
                        items.AppendChild(ele).InnerText = listItem;
                    }
                }
                BindSelectedItem(node);
                if (!string.IsNullOrEmpty(SelectionChangedCommand)) AddBehavior(node, "SelectionChangedBehavior", SelectionChangedCommand);
                if (EnableSetNullByDel) AddGeneralBehavior(node, "ComboBoxDelKeyBehavior", "vg:IsEnabled=\"true\"");
            }
#endif
            ApplyBaseProperty(node);
            list.Add(node);
            return list;

        }
    }

}
